类和对象
和 Java 一样,Dart 也是 class
标识符来定义一个类:
class Student{
...
}
如果用户没有自定义构造函数,会默认生成一个空的构造函数(这个和 Java 一样)
创建对象和 Java 稍有不同,无需使用 new
关键字:
Student studnet = Student();
这样就好了。
函数
普通函数
Dart 并没有 public
、private
之类的关键词,直接就是返回值类型后面跟方法名,如果没有返回值,同样也是 void 修饰。
Dart 虽然没有 private 之类的关键字,但是可以在方法和变量前添加
_
下划线来它们设置为私有的。
构造函数
除了无参构造函数之外,Dart 同样也支持有参构造函数,如果只是单纯的传入参数,可以在构造函数的参数前加 this
关键字来定义:
class Student{
String name;
int age;
Student(this.name, this.age);
}
也可以使用像 Java 一样的构造方法:
class Student {
String name;
int age;
Student(String name, int age) {
this.name = name;
this.age = age;
}
}
在 Java 中我们有时候需要多个构造函数,分别对应不同的参数,在 Dart 中可以这样写:
class Student {
String name;
int age;
Student({this.name, this.age});
@override
String toString() {
return "$name - $age";
}
}
在创建对象时候需要这样:
Student student = Student(name: "张三");
构造函数可以通过别名的方法来创建:
class Student {
String name;
int age;
Student.onlyName(this.name);
}
这样使用:
Student student = Student.onlyName("张三");
setter 和 getter
在 Java 中,我们通常将属性设置为 private
,然后再对外暴露 setter 和 getter 方法以完成赋值和取值,在 Dart 中,我们可以像 Java 那样写,但 Dart 还提供了语法糖,可以简化 setter 和 getter 方法:
class Student {
String _name;
String get name => _name;
set name(String value) {
_name = value;
}
}
方法的级联调用
这也算是 Dart 的语法糖,支持方法级联调用,使用双点的方式:..
,Java 中我们这样写:
Student student = Student();
student.setName("张三");
student.setAge(20);
在 Dart 中可以这样写:
Student student = Student()
..name = "李四"
..age = 55;
方便操作对象,节省代码量。
数据类型
Dart 的数据类型比 Java 要少一些,有如下几种:
数值型,数值型有两种:
- int:整型,位宽由运行平台决定,但是不大于 64 bit
- double:64 bit 双精度浮点数
int 和 double 的父类是 num,也可以直接使用 num 来直接定义数值,具体类型看赋值的是整形还是浮点型
需要注意的是,Drat 中的运算和 Java 稍有不同,在 Java 中,int a = 4,10/a = 2;而在 Dart 中,10/a = 2.5
字符串
布尔型
Set
列表/数组
Map
异步
对于 Java 来讲,我们处理耗时操作是将操作放到一个新开的线程当中执行,待执行完成,再通过线程间通信将计算结果回传给主线程。
Dart 语言是单线程模型的,除非是特殊情况(手动创建 Isolate),否则你的 Dart 代码会运行在主线程当中。
Dart 代码被一个事件循环驱动,就好像 Android 中主线程中的 Looper,我们不断的将任务添加的 Looper 中,系统发现 Looper 不为空的时候,就将任务拿出来执行,也就是说,当我们遇到一些耗时任务的时候(例如 I/O),就会造成线程阻塞。
在实际操作中,这样做显然是不行的,我们总不能遇到一个耗时操作就卡在哪里等吧,所以 Dart 提供了异步工具来帮助我们解决这个问题。
Dart 添加了 async
、await
关键字实现异步的功能,使用起来也很简单,如果我们想要将一个方法设置为异步方法,只需要在方法的大括号前添加 async
即可,当一个方法为异步方法时,其返回值就变成了一个 Future
对象,方法中的返回值和异常都会被包装成一个 Future 对象在执行完成时返回。
///这样是错的,返回值比如是 Future 对象
int test() async {
...
}
///应该这样写
Future<int> test() async {
...
}
只用异步方法的调用,也和正常函数无异,如果需要使用到异步方法的返回值,有两种方法:
使用 then
关键字,当异步方法执行完毕返回返回值时,会执行 then 方法,其中 value 就是异步方法中的返回值(Future<T>
中的 T):
///异步方法
Future<int> test() async {
return 1;
}
///使用
xxx.test().then((value) {
///value 就是异步方法返回的值
});
使用 await
关键字必须在异步方法中,await
标识的方法会变成阻塞状态,直到计算完成返回对应的值:
Future<void> test1() async {
...
}
Future<void> test2() async {
await test1();
...
}
在上面的代码中,test2 方法中调用 test1 方法使用了 await 关键字,所以会一直执行 test1 方法直到 test1 方法执行完,才会继续执行下面的代码。